# K Nearest Neighbors，意思是K个最近的邻居
# 当预测一个新的值x的时候，根据它距离最近的K个点是什么类别来判断x属于哪个类别
from numpy import *
import operator


# ———————————————————————————— pca 开始  ————————————————————————————————
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import pandas as pd

# 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target
print("数组维度：", X.shape)  # 二维数组
iris_dataFrame = pd.DataFrame(X)  # 四维特征矩阵
print("特征矩阵：\n", iris_dataFrame)

pca = PCA(n_components=2)  # n_components设置降维后的特征数，也就是降维后想保留的特征数目。
pca.fit(X)  # 拟合
X_new = pca.transform(X)  # 获取新矩阵
print("X_new:",X_new)
print("y:",y)

# 3. 可视化
plt.figure()  # 获取画布
# 画0这类
plt.scatter(X_new[y == 0, 0], X_new[y == 0, 1], c='red', label=iris.target_names[0])
# 画1这类
plt.scatter(X_new[y == 1, 0], X_new[y == 1, 1], c='blue', label=iris.target_names[1])
# 画2这类
plt.scatter(X_new[y == 2, 0], X_new[y == 2, 1], c='green', label=iris.target_names[2])
plt.legend()  # 显示图例
plt.show()
# ———————————————————————————— pca 结束  ————————————————————————————————
#定义KNN算法分类器函数
#函数参数包括：(测试数据，训练数据，分类, k值)   K=3就是找最近的3个点看看标签哪个最多，若K=5就看看最近5个标签哪个占比最多
def classify(inX,dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX,(dataSetSize,1))-dataSet
    sqDiffMat=diffMat**2
    sqDistances=sqDiffMat.sum(axis=1)
    distances=sqDistances**0.5 #计算欧式距离
    sortedDistIndicies=distances.argsort() #排序并返回index
    #选择距离最近的k个值
    classCount={}
    for i in range(k):
        voteIlabel=labels[sortedDistIndicies[i]]
        #D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.
        classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
    #排序
    sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]


#定义一个生成“训练样本集”的函数，包含特征和分类信息
def createDataSet():
    group=array(X_new)   #有150个数据
    labels=y    #这150个数据对应的标签
    return group,labels

#生成训练样本
group,labels=createDataSet()
#对测试数据[0,0]进行KNN算法分类测试
result = classify([0,1000000],group,labels,3)
print(result)



